package com.easylinkin.linkappapi.reportCenter.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.reportCenter.entity.Report;
import com.easylinkin.linkappapi.reportCenter.entity.base.ReportBase;
import com.easylinkin.linkappapi.reportCenter.entity.dto.ReportDetailDTO;
import com.easylinkin.linkappapi.reportCenter.mapper.ReportMapper;
import com.easylinkin.linkappapi.reportCenter.service.ReportBaseService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

/**
 * @Description 报告基础服务
 * @Author kan yuanfeng
 * @Date 2023/7/17 11:51
 */
public abstract class ReportBaseServiceImpl<T extends ReportBase> implements ReportBaseService<T> {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 查询reportId当月数据
     * @param reportId
     * @param type (两个数据在一张表时才有)
     * @return
     */
    protected abstract List<T> getByReportId(Integer reportId,Integer type);

    /**
     * 根据时间获取上月数据
     * @param date
     * @param type (两个数据在一张表时才有)
     * @return
     */
    protected abstract List<T> getLastByDate(String tenantId,Date date,Integer type);

    /**
     * 查询上月数据
     * @param type (两个数据在一张表时才有)
     */
    private List<T> getLast(Integer reportId,Integer type){
        List<T> lastData;
        //获取上个月的报告id
        Report last = reportMapper.findLast(reportId);
        if (null != last){
            lastData = getByReportId(last.getId(),type);
        }else {
            Report report = reportMapper.selectById(reportId);
            lastData = getLastByDate(report.getTenantId(), DateUtil.offsetMonth(report.getStartTime(), -1),type);
        }
        return lastData;
    }

    /**
     * 月数据处理
     * @param type (两个数据在一张表时才有)
     */
    @Override
    public ReportDetailDTO dataHandler(Integer reportId, String name, Integer type, BiConsumer<T,T> biConsumer){
        //本月数据
        List<T> curData = getByReportId(reportId,type);
        //上月数据
        List<T> lastData = getLast(reportId,type);
        //求设备名称
        List<Device> deviceList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(curData)){
            List<String> codes = curData.stream().filter(l -> StringUtils.isNotBlank((String)ReflectUtil.getFieldValue(l,"deviceCode")))
                    .map(l -> (String)ReflectUtil.getFieldValue(l,"deviceCode")).collect(Collectors.toList());
            QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("code",codes);
            deviceList = deviceMapper.selectList(queryWrapper);
        }
        if (CollectionUtil.isNotEmpty(curData)){
            List<Device> finalDeviceList = deviceList;
            curData.forEach(c->{
                if (CollectionUtil.isNotEmpty(finalDeviceList)){
                    List<Device> devices = finalDeviceList.stream().filter(d -> d.getCode().equals((String)ReflectUtil.getFieldValue(c,"deviceCode"))).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(devices)){
                        c.setDeviceName(devices.get(0).getName());
                    }
                }
                String deviceCode = (String)ReflectUtil.getFieldValue(c,"deviceCode");
                T last;
                if (StringUtils.isNotBlank(deviceCode)){
                    last = lastData.stream().filter(l -> deviceCode.equals(ReflectUtil.getFieldValue(l, "deviceCode"))).findFirst().orElse(null);
                }else {
                    last = lastData.stream().filter(l -> StringUtils.isBlank((String)ReflectUtil.getFieldValue(l,"deviceCode"))).findFirst().orElse(null);
                }
                if (null != last){
                    c.setLastNum((Integer) ReflectUtil.getFieldValue(last,"num"));
                    c.computeRatio();
                    //特殊处理
                    if (null != biConsumer){
                        biConsumer.accept(c,last);
                    }
                }
            });
            //汇总
            ReportDetailDTO aiReportDetailDTO = new ReportDetailDTO<>();
            aiReportDetailDTO.setName(name);
            aiReportDetailDTO.setItem(curData);
            return aiReportDetailDTO;
        }else {
            return null;
        }
    }
}
